package com.icinfo.cloud.provider.punish.ucase.app.controller.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.ApiVisitDataSourceEnum;
import com.icinfo.cloud.provider.common.enums.DocumentKindEnum;
import com.icinfo.cloud.provider.common.enums.OpinionType;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.peripheralinterface.xzzf.service.IXzzfInterfaceService;
import com.icinfo.cloud.provider.punish.approval.constant.AuditStatusConstant;
import com.icinfo.cloud.provider.punish.approval.dto.AuditNextUserQueryDto;
import com.icinfo.cloud.provider.punish.approval.mapper.CaseApprovalCompleteRecordMapper;
import com.icinfo.cloud.provider.punish.approval.mapper.CaseApprovalFlowRelationMapper;
import com.icinfo.cloud.provider.punish.approval.mapper.CaseApprovalWaitRecordMapper;
import com.icinfo.cloud.provider.punish.approval.model.CaseApprovalCompleteRecord;
import com.icinfo.cloud.provider.punish.approval.model.CaseApprovalFlowRelation;
import com.icinfo.cloud.provider.punish.approval.model.CaseApprovalWaitRecord;
import com.icinfo.cloud.provider.punish.approval.service.ICaseApprovalWaitRecordService;
import com.icinfo.cloud.provider.punish.approval.vo.NextAuditUserVo;
import com.icinfo.cloud.provider.punish.common.caseregister.service.IRegisterCommonService;
import com.icinfo.cloud.provider.punish.common.documentoperate.dto.StageDocCommonOperateSaveDto;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentRecordStatusEnum;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentStatusEnum;
import com.icinfo.cloud.provider.punish.common.documentoperate.service.IStageDocCommonOperateService;
import com.icinfo.cloud.provider.punish.common.systemmessage.dto.SystemMessageInsertDto;
import com.icinfo.cloud.provider.punish.common.systemmessage.service.ICaseSystemMessageService;
import com.icinfo.cloud.provider.punish.config.mapper.ConfigBusiParamDocumentInfoMapper;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamDocumentInfo;
import com.icinfo.cloud.provider.punish.config.model.SysDepartParam;
import com.icinfo.cloud.provider.punish.config.service.IConfigBusiParamDocumentInfoService;
import com.icinfo.cloud.provider.punish.config.service.ISysDepartParamService;
import com.icinfo.cloud.provider.punish.csource.manage.dto.FlowCommonDto;
import com.icinfo.cloud.provider.punish.csource.manage.mapper.CaseSourcePartyInfoMapper;
import com.icinfo.cloud.provider.punish.csource.manage.mapper.CaseSourceRegisterMainInfoMapper;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourcePartyInfo;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceRegisterMainInfo;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceFlowRecordService;
import com.icinfo.cloud.provider.punish.ucase.app.controller.service.AppCaseClosingApprovalService;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseStatusEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.mapper.CaseDocumentRecordMapper;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseDocumentRecord;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainInfoStatusChangeRecord;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICaseHandlePersonRecordService;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICaseMainInfoService;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICaseMainInfoStatusChangeRecordService;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.ICasePartiesRecordService;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseHandlePersonRecordVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesRecordVo;
import com.icinfo.cloud.provider.punish.ucase.investigateevidence.enums.CaseStatusChangeEffectEnum;
import com.icinfo.cloud.provider.punish.ucase.investigateevidence.enums.CaseStatusChangeTypeEnum;
import com.icinfo.cloud.provider.punish.usersign.mapper.MemberUserSignMapper;
import com.icinfo.cloud.workflow.common.annotation.WorkFlowRollAnnotation;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.cloud.xzcf.provider.member.userinfo.model.MemberUserInfo;
import com.icinfo.cloud.xzcf.provider.member.zfpeople.dto.ZfPeopleBaseInfoVO;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import com.icinfo.framework.tools.utils.DateUtils;
import com.icinfo.framework.tools.utils.MapUtils;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = {Error.class, Exception.class})
@Slf4j
public class AppCaseClosingApprovalServiceImpl implements AppCaseClosingApprovalService {

    @Resource
    private ICaseMainInfoService caseMainInfoService;

    @Resource
    private IConfigBusiParamDocumentInfoService configBusiParamDocumentInfoService;

    @Resource
    private CaseSourceRegisterMainInfoMapper caseSourceRegisterMainInfoMapper;

    @Resource
    private ICaseSourceFlowRecordService caseSourceFlowRecordService;

    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;

    @Resource
    private ICaseMainInfoStatusChangeRecordService caseMainInfoStatusChangeRecordService;

    @Resource
    private CaseApprovalFlowRelationMapper caseDocuApprovalFolwRelationMapper;

    @Resource
    private ISysDepartParamService sysDepartParamService;

    @Resource
    private CaseApprovalWaitRecordMapper caseApprovalWaitRecordMapper;

    @Resource
    private ConfigBusiParamDocumentInfoMapper configBusiParamDocumentInfoMapper;

    @Resource
    private CaseSourcePartyInfoMapper caseSourcePartyInfoMapper;

    @Resource
    private ICasePartiesRecordService casePartiesRecordService;

    @Resource
    private IXzzfInterfaceService xzzfInterfaceService;

    @Resource
    private CaseApprovalCompleteRecordMapper caseApprovalCompleteRecordMapper;

    @Resource
    private IRegisterCommonService iRegisterCommonService;

    @Resource
    private IStageDocCommonOperateService stageDocCommonOperateService;

    @Resource
    private ICaseApprovalWaitRecordService caseApprovalWaitRecordService;

    @Resource
    private MemberUserSignMapper memberUserSignMapper;

    @Resource
    private ICaseHandlePersonRecordService caseHandlePersonRecordService;

    @Resource
    private ICaseSystemMessageService caseSystemMessageService;

    @Value("${ding.sendUrl}")
    private String dingSendUrl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @WorkFlowRollAnnotation
    public Map<String, Object> documentGeneralSubmit(String caseId, String documentCatalogCode, String userId, String opinion,String partyId,String caseAssistId,String isAutoApproval,String autoTime,String docId,String isEditApproval) {
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        //判断是否需要滚流程
        boolean isCaseSourceRoll=getIsCaseSourceRoll(caseMainInfo,documentCatalogCode);
        //判断是否需要保存日志
        boolean isSaveCaseSourceFlow=getIsSaveCaseSourceFolwLog(caseMainInfo,documentCatalogCode);
        if(isSaveCaseSourceFlow){
            CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseMainInfo.getId());
            //设置案源流程阶段
            if(CaseStatusEnum.PUNISH_NO_REGISTER.getCode().equals(caseMainInfo.getCaseStatus())) {
                caseSourceRegisterMainInfo.setCaseSourceStageCode(Constant.CASE_SOURCE_STAGE_BYLASP);
            }else{
                caseSourceRegisterMainInfo.setCaseSourceStageCode(Constant.CASE_SOURCE_STAGE_LASP);
            }
            caseSourceRegisterMainInfoMapper.updateByPrimaryKeySelective(caseSourceRegisterMainInfo);
            saveCaseSourceFlow(caseSourceRegisterMainInfo, caseMainInfo);
        }
        if (caseMainInfoService.validateCaseIsInNotDealStatus(caseMainInfo, null)) {
            ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
            String documentKindCode = configBusiParamDocumentInfo.getDocumentKindCode();
            if (!caseMainInfoService.validateIsTerminateCaseWhenBreakOff(caseMainInfo, null, documentKindCode)) {
                throw new BusinessException("当前案件状态不允许进行该操作");
            }
        }
        String handleType=caseMainInfo.getHandleType();
        //更新文书记录表
        Example exampleDocRecord = new Example(CaseDocumentRecord.class);
        //特殊处理文书暂停文书,更正公示文书
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
        CaseDocumentRecord caseDocumentRecord=null;
        if(StringUtils.isNotBlank(docId)) {
            caseDocumentRecord = caseDocumentRecordMapper.selectByPrimaryKey(docId);
        }
        if(org.springframework.util.ObjectUtils.isEmpty(caseDocumentRecord)) {
            if (ObjectUtil.isNotEmpty(configBusiParamDocumentInfo)
                    && CaseStatusChangeTypeEnum.SUSPEND.getDocumentKindCode().equals(configBusiParamDocumentInfo.getDocumentKindCode())) {
                CaseMainInfoStatusChangeRecord changeRecord = caseMainInfoStatusChangeRecordService.getCaseMainInfoStatusChangeRecordByChangeType(caseId, CaseStatusChangeTypeEnum.SUSPEND.getCode());
                if (ObjectUtil.isNotEmpty(changeRecord)
                        && CaseStatusChangeEffectEnum.INVALID.getCode().equals(changeRecord.getStatus())) {
                    exampleDocRecord.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode).andEqualTo("id", changeRecord.getDocumentId());
                }
            } else if (StringUtils.isBlank(partyId)) {
                exampleDocRecord.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode).andNotEqualTo("documentRecordStatus", DocumentRecordStatusEnum.WITHDRAW.getCode());
            } else {
                exampleDocRecord.createCriteria().andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", documentCatalogCode).andEqualTo("partyId", partyId).andNotEqualTo("documentRecordStatus", DocumentRecordStatusEnum.WITHDRAW.getCode());
            }
            exampleDocRecord.orderBy("documentCreateTime").desc();
            List<CaseDocumentRecord> caseDocumentRecords = caseDocumentRecordMapper.selectByExample(exampleDocRecord);
            if (caseDocumentRecords.isEmpty()) {
                throw new BusinessException("未匹配到文书记录");
            }
            caseDocumentRecord = caseDocumentRecords.get(0);
        }
        caseDocumentRecord.setDocumentAuditStatus("pending");
        caseDocumentRecord.setDocumentApprovalStatus(DocumentStatusEnum.CHECKING.getCode());
        // 更新关联文书

        //updateRelationDocStatus(documentCatalogCode,"pending",caseId,partyId);
        updateRelationDocStatusByApprovalDocumentId(documentCatalogCode,"pending",caseId,partyId, caseDocumentRecord.getId());
        //查询审批关系表
        List<CaseApprovalFlowRelation> nextFlow = getNextCaseApprovalFlow(null, documentCatalogCode);
        if (nextFlow == null || nextFlow.size() == 0) {
            throw new BusinessException("未找到下一环节关系数据!");
        }
        // 生成待审批记录
        //判断审批记录是否存在
        boolean isExist = false;
        if (ObjectUtils.isEmpty(docId)) {
            isExist=checkCaseApprovalWaitRecordIsExist(caseId,documentCatalogCode,partyId);
        } else {
            isExist=checkCaseApprovalWaitRecordIsExistByDocumentId(caseId, caseDocumentRecord.getId());
        }
        if(isExist){
            throw new BusinessException("生成待审批记录已存在，请勿重复提交!");
        }
        CaseApprovalWaitRecord caseApprovalWaitRecord = new CaseApprovalWaitRecord();
        caseApprovalWaitRecord.setId(StringUtils.uuid());
        caseApprovalWaitRecord.setApprovalNum(nextFlow.get(0).getApprovalOrderNum());
        caseApprovalWaitRecord.setCaseId(caseId);
        caseApprovalWaitRecord.setApprovalStatus(AuditStatusConstant.AUDIT_STATUS_WAIT);
        if (StringUtils.isNotBlank(nextFlow.get(0).getApprovalTerm())) {
            Integer term = nextFlow.get(0).getApprovalTerm().contains("天") ? new Integer(nextFlow.get(0).getApprovalTerm().substring(0, nextFlow.get(0).getApprovalTerm().length() - 1)) : new Integer(nextFlow.get(0).getApprovalTerm());
            caseApprovalWaitRecord.setApprovalCurrentLimitTime(term);
            caseApprovalWaitRecord.setApprovalCurrentPlanendTime(DateUtils.addDays(new Date(), term));
        }
        UserDTO userDTO = UserUtil.getUserInfo();
        caseApprovalWaitRecord.setAddUserId(userDTO.getUserId().toString());
        caseApprovalWaitRecord.setAddUserName(userDTO.getRealName());
        caseApprovalWaitRecord.setDocumentId(documentCatalogCode);
        caseApprovalWaitRecord.setFlowRelationId(nextFlow.get(0).getId());
        //标题：行政处罚的相关审批任务标题为：当事人名称+“的”+文书名称；如“张三的立案审批表”
        //CaseMainInfoVo caseMainInfoVo=caseMainInfoMapper.selectCaseMainInfo(caseId);
        String title = "";
        Example examplePd = new Example(ConfigBusiParamDocumentInfo.class);
        examplePd.createCriteria().andEqualTo("documentCatalogCode", documentCatalogCode);
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = configBusiParamDocumentInfoMapper.selectByExample(examplePd);
        if(CaseStatusEnum.PUNISH_NO_REGISTER.getCode().equals(caseMainInfo.getCaseStatus())&& ApiVisitDataSourceEnum.PUNISH_AY.getCode().equals(caseMainInfo.getDataSource())){
            Example example=new Example(CaseSourcePartyInfo.class);
            example.createCriteria().andEqualTo("caseSourceId",caseMainInfo.getId()).andEqualTo("status",Constant.STRING_1);
            List<CaseSourcePartyInfo> caseSourcePartyInfos=caseSourcePartyInfoMapper.selectByExample(example);
            if(caseSourcePartyInfos!=null&&caseSourcePartyInfos.size()>0){
                CaseSourceRegisterMainInfo caseSourceRegisterMainInfo=caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseMainInfo.getId());
                title=caseSourceRegisterMainInfo.getPartyName()+"的"+configBusiParamDocumentInfos.get(0).getDocumentKindName();
            }else{
                title=configBusiParamDocumentInfos.get(0).getDocumentKindName();
            }

        }else{
            List<CasePartiesRecordVo> partiesRecords = casePartiesRecordService.getCasePartiesInfo(caseId);
            CasePartiesRecordVo firstPartyInfo = partiesRecords.get(Constant.INTEGER_0);
            String showPartyName = firstPartyInfo.getPartyName();
            if (partiesRecords.size() == 1){
                title = showPartyName + "的" + configBusiParamDocumentInfos.get(0).getDocumentKindName();
            } else if(partiesRecords.size() > 1){
                title = showPartyName + "等" + partiesRecords.size() + "个的" + configBusiParamDocumentInfos.get(0).getDocumentKindName();
            }
        }
        caseApprovalWaitRecord.setApprovalTitle(title);
        caseApprovalWaitRecord.setAddTime(new Date());
        if(StringUtils.isNotEmpty(caseAssistId)){
            caseApprovalWaitRecord.setCaseAssistId(caseAssistId);
        }
        List<ZfPeopleBaseInfoVO> baseInfo = null;
        if (StringUtils.isBlank(userId)) {
            AuditNextUserQueryDto queryDto = new AuditNextUserQueryDto();
            queryDto.setCaseId(caseId);
            queryDto.setDocumentCatalogCode(documentCatalogCode);
            List<NextAuditUserVo> users = caseApprovalWaitRecordService.getNextNodeUser(queryDto);
            caseApprovalWaitRecord.setApprovalUserId(users.get(0).getUserId());
            caseApprovalWaitRecord.setApprovalUserName(users.get(0).getRealName());
        } else {
            JSONObject baseInfoRequest = new JSONObject();
            List<String> userIds = Arrays.asList(userId.split(","));
            baseInfoRequest.put("userIds", userIds);
            baseInfo = xzzfInterfaceService.getZfPeopleList(baseInfoRequest);
            caseApprovalWaitRecord.setApprovalUserId(userId);
            StringJoiner stringJoiner = new StringJoiner(",");
            for (ZfPeopleBaseInfoVO vo : baseInfo){
                stringJoiner.add(vo.getName());
            }
            caseApprovalWaitRecord.setApprovalOrgName(caseMainInfo.getCaseOrgName());
            caseApprovalWaitRecord.setApprovalUserName(stringJoiner.toString());
            caseApprovalWaitRecord.setApprovalOrgCode(caseMainInfo.getCaseOrgCode());
            caseApprovalWaitRecord.setPartyId(partyId);
        }
        caseApprovalWaitRecord.setIsAutoApproval(isAutoApproval);
        caseApprovalWaitRecord.setAutoTime(autoTime);
        caseApprovalWaitRecord.setDocId(docId);
        caseApprovalWaitRecord.setIsEditApproval(isEditApproval);
        // 生成待审批记录
        int insert = this.caseApprovalWaitRecordMapper.insert(caseApprovalWaitRecord);
        // 生成发起人完成记录，审批序号设为零。供审批日志链使用，userId设为空防止我已审批查出来
        CaseApprovalCompleteRecord caseApprovalCompleteRecord = new CaseApprovalCompleteRecord();
        BeanUtils.copyProperties(caseApprovalWaitRecord, caseApprovalCompleteRecord);
        caseApprovalCompleteRecord.setId(StringUtils.uuid());
        caseApprovalCompleteRecord.setApprovalUserId("");
        caseApprovalCompleteRecord.setApprovalNum("0");
        caseApprovalCompleteRecord.setApprovalTime(new Date());
        caseApprovalCompleteRecord.setApprovalOpinion(opinion);
        caseApprovalCompleteRecord.setApprovalUserName(null);
        caseApprovalCompleteRecord.setApprovalOrgName(userDTO.getOrgName());
        caseApprovalCompleteRecord.setPartyId(partyId);
        caseApprovalCompleteRecord.setDocId(docId);
        int complete = this.caseApprovalCompleteRecordMapper.insert(caseApprovalCompleteRecord);
        int updateResult = caseDocumentRecordMapper.updateByPrimaryKeySelective(caseDocumentRecord);
        Boolean f = updateResult == 1 && insert == 1 && complete == 1;
        Map<String, Object> result = new HashMap<>(8);
        result.put("documentId", caseDocumentRecord.getId());
        if (f) {
            // 生成文书
            setUnderTakeOpinion(caseId, documentCatalogCode, opinion, caseDocumentRecord, userDTO,partyId,isEditApproval,docId);
            if(!isCaseSourceRoll){
                result.put("success","true");
                result.put("msg","成功");
                return result;
            }
            if(!Constant.STRING_1.equals(isEditApproval)) {
                result.put("workId", caseId);
            }
            String documentLinkObjectType = configBusiParamDocumentInfos.get(0).getDocumentLinkObjectType();
            if(Constant.STRING_2.equals(handleType) &&  Constant.STRING_2.equals(documentLinkObjectType)){
                result.put("workSubId", partyId);
            }
            if(!Constant.STRING_1.equals(isEditApproval)) {
                result.put("closeSignal", "CLOSE-TRIGGER-APPROVAL");
                result.put("documentCatalogCode", documentCatalogCode);
            }
            if(StringUtils.isNotBlank(caseAssistId)){
                result.put("workAssistId", caseAssistId);
            }
           /* if(Constant.STRING_1.equals(isAutoApproval)&&Constant.STRING_3.equals(caseMainInfo.getCaseType())){
                doAutoApproval(autoTime,caseId,documentCatalogCode,caseMainInfo);
            }*/
            // 发送钉钉提醒
            //sendNewAuditDing(caseId, documentCatalogCode, caseApprovalWaitRecord.getApprovalCurrentLimitTime(), baseInfo);
            sendNewAuditDingMsg(caseId, documentCatalogCode, caseApprovalWaitRecord.getApprovalCurrentLimitTime(), Arrays.asList(userId.split(",")));
            //工作台-消息提醒
            sendNewAuditPcMsg(caseId,caseMainInfo.getCaseOrgName(),documentCatalogCode,configBusiParamDocumentInfo.getDocumentCatalogName(),caseApprovalWaitRecord,caseMainInfo.getCaseOrgCode(),Arrays.asList(userId.split(",")));
        } else {
            throw new BusinessException("文书提交审批时出现异常");
        }
        return result;
    }

    /**
     * 是否滚流程
     * @author liyafeng
     * @date 2022/8/19
     * @param caseMainInfo
     * @param documentCatalogCode
     * @return {@link boolean}
     */
    private boolean getIsCaseSourceRoll(CaseMainInfoVo caseMainInfo, String documentCatalogCode) {
        boolean isCaseSoureRoll=true;
        //案源来源审批数据 提交审批完成后 新增流转日志
        if(ApiVisitDataSourceEnum.PUNISH_AY.getCode().equals(caseMainInfo.getDataSource())){
            ConfigBusiParamDocumentInfo configBusiParamDocumentInfo=configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
            String kindCode=configBusiParamDocumentInfo.getDocumentKindCode();
            /*if(kindCode.equals("LASPB")||kindCode.equals("DT2BYLASPB")) {
                CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseMainInfo.getId());
                saveCaseSourceFlow(caseSourceRegisterMainInfo, caseMainInfo);
            }*/
            if(kindCode.equals("DT2BYLASPB")){
                isCaseSoureRoll=false;
            }
        }
        return isCaseSoureRoll;
    }

    /**
     * 是否存日志
     * @author liyafeng
     * @date 2022/8/19
     * @param
     * @return {@link boolean}
     */
    private boolean getIsSaveCaseSourceFolwLog(CaseMainInfoVo caseMainInfo, String documentCatalogCode){
        boolean isSaveCaseSourceFolwLog=false;
        if(ApiVisitDataSourceEnum.PUNISH_AY.getCode().equals(caseMainInfo.getDataSource())){
            ConfigBusiParamDocumentInfo configBusiParamDocumentInfo=configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
            String kindCode=configBusiParamDocumentInfo.getDocumentKindCode();
            if(kindCode.equals("LASPB")||kindCode.equals("DT2BYLASPB")) {
                /*CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = caseSourceRegisterMainInfoMapper.selectByPrimaryKey(caseMainInfo.getId());
                saveCaseSourceFlow(caseSourceRegisterMainInfo, caseMainInfo);*/
                isSaveCaseSourceFolwLog=true;
            }

        }
        return  isSaveCaseSourceFolwLog;
    }

    /**
     * 案源立案流转日志保存
     * @author liyafeng
     * @date 2022/8/18
     * @param caseSourceRegisterMainInfo
     * @return
     */
    private void saveCaseSourceFlow(CaseSourceRegisterMainInfo caseSourceRegisterMainInfo,CaseMainInfoVo caseMainInfo) {
        FlowCommonDto flowCommonDto=new FlowCommonDto();
        UserDTO userDTO=UserUtil.getUserInfo();
        flowCommonDto.setCaseSourceId(caseSourceRegisterMainInfo.getId());
        flowCommonDto.setStartPersonName(userDTO.getRealName());
        flowCommonDto.setStartPersonOrgName(userDTO.getOrgName());
        flowCommonDto.setFlowStartTime(new Date());
        flowCommonDto.setFlowEndTime(new Date());
        flowCommonDto.setStartPersonDeptName(userDTO.getDeptName());
        if(CaseStatusEnum.PUNISH_NO_REGISTER.getCode().equals(caseMainInfo.getCaseStatus())) {
            flowCommonDto.setFlowStageType(Constant.CASE_SOURCE_STAGE_BYLASP);
        }else{
            flowCommonDto.setFlowStageType(Constant.CASE_SOURCE_STAGE_LASP);
        }
        caseSourceFlowRecordService.saveCommonFlowRecord(flowCommonDto);
    }

    /**
     * 【V1.11.0】描述： 更新关联文书状态
     *
     * @param documentCatalogCode
     * @param approvalStatus
     * @param caseId
     * @param partyId
     * @param documentId
     */
    private void updateRelationDocStatusByApprovalDocumentId(String documentCatalogCode,String approvalStatus,String caseId,String partyId, String documentId){
        // 查询关联文书
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
        if (StringUtils.isNotBlank(configBusiParamDocumentInfo.getRelationDocumentCatalogCode())){
            String fg = ",";
            String[] relationDocs = configBusiParamDocumentInfo.getRelationDocumentCatalogCode().split(fg);
            for (int i = 0; i < relationDocs.length; i++) {
                Example example = new Example(CaseDocumentRecord.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("caseId", caseId).andEqualTo("documentCatalogCode", relationDocs[i]).andNotEqualTo("documentRecordStatus", DocumentRecordStatusEnum.WITHDRAW.getCode())
                        .andNotEqualTo("documentApprovalStatus",DocumentStatusEnum.CHECK_END.getCode());
                if(StringUtils.isNotBlank(partyId)){
                    criteria.andEqualTo("partyId", partyId);
                }
                //补正更正文书处理
                if (DocumentKindEnum.DOC_KIND_DK1BZGZSPB.getCode().equals(configBusiParamDocumentInfo.getDocumentKindCode())
                        && StringUtils.isNotBlank(documentId)) {
                    criteria.andEqualTo("relationApprovalDocumentId", documentId);
                }

                List<CaseDocumentRecord> updateRecord = caseDocumentRecordMapper.selectByExample(example);

                if (!updateRecord.isEmpty()){
                    CaseDocumentRecord record = updateRecord.get(0);
                    record.setDocumentAuditStatus(approvalStatus);
                    String pass = "pass";
                    String pending = "pending";
                    String rt = "return";
                    // 状态判断更新
                    if (pass.equals(approvalStatus)){
                        record.setDocumentApprovalTime(LocalDateTime.now());
                        record.setDocumentApprovalStatus(DocumentStatusEnum.CHECK_END.getCode());
                    }
                    if (pending.equals(approvalStatus)){
                        record.setDocumentApprovalStatus(DocumentStatusEnum.CHECKING.getCode());
                    }
                    if (rt.equals(approvalStatus)){
                        record.setDocumentApprovalStatus(DocumentStatusEnum.CHECK_BACK.getCode());
                    }
                    caseDocumentRecordMapper.updateByPrimaryKeySelective(record);
                }
            }
        }
    }

    /**
     * 查询下一环节配置
     * @param currentRecord
     * @param docId
     * @return
     */
    private List<CaseApprovalFlowRelation> getNextCaseApprovalFlow(CaseApprovalWaitRecord currentRecord, String docId) {
        if (currentRecord != null) {
            CaseApprovalFlowRelation relation = caseDocuApprovalFolwRelationMapper.selectByPrimaryKey(currentRecord.getFlowRelationId());
            if (relation == null) {
                throw new BusinessException("系统异常，内部错误！");
            }
            Example exampleRelation = new Example(CaseApprovalFlowRelation.class);
            Integer sort = Integer.valueOf(relation.getApprovalOrderNum()) + 1;
            // 版本号条件/新增有效字段
            exampleRelation.createCriteria().andEqualTo("documentCatalogCode", relation.getDocumentCatalogCode()).andEqualTo("approvalOrderNum", sort.toString())
                    .andEqualTo("approvalFlowVerson", relation.getApprovalFlowVerson()).andEqualTo("approvalFlowId", relation.getApprovalFlowId());
            List<CaseApprovalFlowRelation> nextFlow = caseDocuApprovalFolwRelationMapper.selectByExample(exampleRelation);
            return nextFlow;
        } else {
            //处罚决定书审批表 第一次需要根据是否乡镇机构 判断是否需要走联合法制审核
            //根据文书目录编码判断类型是否为处罚决定书审批表
            ConfigBusiParamDocumentInfo configBusiParamDocumentInfo=configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(docId);
            String kindCode=configBusiParamDocumentInfo.getDocumentKindCode();
            //根据用户部门查询是否需要联合法制审核审批
            boolean centerRelationFlag=false;
            UserDTO userDTO=UserUtil.getUserInfo();
            String cfjdsspbKindCode="CFJDSPB";
            String cfgzspbKindCode="CFGZSPB";
            if(cfjdsspbKindCode.equals(kindCode)||cfgzspbKindCode.equals(kindCode)){
                SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCode(userDTO.getOrgCode(),userDTO.getDeptCode());
                if(ObjectUtil.isNotEmpty(sysDepartParam) && "1".equals(sysDepartParam.getIsApprovalCenterUsing())){
                    centerRelationFlag=true;
                }
            }
            if(centerRelationFlag){
                List<CaseApprovalFlowRelation> centerApprovalRelationList=new ArrayList<>();
                Example example = new Example(CaseApprovalFlowRelation.class);
                // 版本号条件/新增有效字段
                example.createCriteria().andEqualTo("documentCatalogCode", docId).andEqualTo("isNowVersion", "1").andEqualTo("isApprovalCenter","1");
                List<CaseApprovalFlowRelation> centerRelationList  = caseDocuApprovalFolwRelationMapper.selectByExample(example);
                if(null!=centerRelationList&&centerRelationList.size()>0){
                    CaseApprovalFlowRelation centerRelation= centerRelationList.get(0);
                    Example centerRelationListExample = new Example(CaseApprovalFlowRelation.class);
                    // 版本号条件/新增有效字段
                    centerRelationListExample.createCriteria().andEqualTo("documentCatalogCode", docId).andEqualTo("isNowVersion", "1").andEqualTo("approvalFlowId",centerRelation.getApprovalFlowId());
                    centerRelationListExample.orderBy("approvalOrderNum").asc();
                    centerApprovalRelationList  = caseDocuApprovalFolwRelationMapper.selectByExample(centerRelationListExample);
                }
                return centerApprovalRelationList;
            }
            Example example = new Example(CaseApprovalFlowRelation.class);
            // 版本号条件/新增有效字段
            example.createCriteria().andEqualTo("documentCatalogCode", docId).andEqualTo("isNowVersion", "1").andNotEqualTo("approvalFlowId","4F9B01BFE80849E2A4C06C9CEDA7E83B");
            example.orderBy("approvalOrderNum").asc();
            List<CaseApprovalFlowRelation> list  = caseDocuApprovalFolwRelationMapper.selectByExample(example);
            // 最新版流程没有
            if (list.isEmpty()){
                example.clear();
                example.createCriteria().andEqualTo("documentCatalogCode", docId);
                example.orderBy("approvalFlowVerson").desc();
                example.orderBy("approvalOrderNum").asc();
                list = caseDocuApprovalFolwRelationMapper.selectByExample(example);
            }
            return list;
        }
    }

    /**
     * 判断待审批记录是否存在
     * @author liyafeng
     * @date 2022/7/14
     * @param caseId
     * @param documentCatalogCode
     * @param partyId
     * @return {@link boolean}
     */
    private boolean checkCaseApprovalWaitRecordIsExist(String caseId, String documentCatalogCode, String partyId) {
        boolean isExist=false;
        Example example=new Example(CaseApprovalWaitRecord.class);
        if(StringUtils.isBlank(partyId)){
            example.createCriteria().andEqualTo("caseId",caseId).andEqualTo("documentId",documentCatalogCode);
        }else{
            example.createCriteria().andEqualTo("caseId",caseId).andEqualTo("documentId",documentCatalogCode).andEqualTo("partyId",partyId);
        }
        List<CaseApprovalWaitRecord> caseApprovalWaitRecords=caseApprovalWaitRecordMapper.selectByExample(example);
        if(null!=caseApprovalWaitRecords&&caseApprovalWaitRecords.size()>0){
            isExist=true;
        }
        return isExist;
    }

    /**
     * 【V1.11.0】描述： 判断待审批记录是否存在
     * @param caseId
     * @param documentId
     * @return {@link boolean}
     */
    private boolean checkCaseApprovalWaitRecordIsExistByDocumentId(String caseId, String documentId) {
        boolean isExist=false;
        Example example=new Example(CaseApprovalWaitRecord.class);
        example.createCriteria().andEqualTo("caseId", caseId).andEqualTo("docId", documentId);
        List<CaseApprovalWaitRecord> caseApprovalWaitRecords=caseApprovalWaitRecordMapper.selectByExample(example);
        if(null!=caseApprovalWaitRecords&&caseApprovalWaitRecords.size()>0){
            isExist=true;
        }
        return isExist;
    }

    /**
     *  文书添加承办人意见
     * @param caseId
     * @param documentCatalogCode
     * @param opinion
     * @param caseDocumentRecord
     * @param userDTO
     */
    private void setUnderTakeOpinion(String caseId, String documentCatalogCode, String opinion, CaseDocumentRecord caseDocumentRecord, UserDTO userDTO,String partyId,String isEditApproval,String docId) {
        StageDocCommonOperateSaveDto saveDto = new StageDocCommonOperateSaveDto();
        saveDto.setCaseId(caseId);
        saveDto.setPartyId(partyId);
        saveDto.setDocumentCatalogCode(documentCatalogCode);
        JSONObject jsonObject = JSON.parseObject(caseDocumentRecord.getDocumentContent());
        HashMap<String, Object> jsonMap = new HashMap<>(16);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            jsonMap.put(entry.getKey(), entry.getValue());
        }
        String approvalStatus = DocumentStatusEnum.CHECKING.getCode();
        // 承办人意见
        jsonMap.put(OpinionType.CBR.getDocCode(), opinion);
        jsonMap.put(OpinionType.CBR.getAuditTimeCode(), LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
        String sign = iRegisterCommonService.getHandleSignData(userDTO.getUserId().toString());
        jsonMap.put(OpinionType.CBR.getAuditUserIdCode(),sign);
        saveDto.setDataMap(jsonMap);
        saveDto.setIsUpdateRelationTable(Constant.STRING_0);
        saveDto.setDocumentApprovalStatus(approvalStatus);
        saveDto.setIsEditFile(isEditApproval);
        saveDto.setDocId(docId);
        Map<String, Object> stringObjectMap = stageDocCommonOperateService.saveDocInfo(saveDto);
        String status = MapUtils.getString(stringObjectMap, "success", "");
        String tr = "true";
        if (!tr.equals(status)) {
            throw new BusinessException("文书生成失败！");
        }
    }

    /**
     * 新审批 审批人钉钉消息（新加--兼容发送管理人员的政务钉钉信息）
     * @param caseId
     * @param documentCatalogCode
     * @param term
     * @param userIdList
     */
    private void sendNewAuditDingMsg(String caseId, String documentCatalogCode, Integer term, List<String> userIdList) {
        //获取执法人员和领导的政务钉钉id
        //List<ZfAndManageUserInfoVO> list = xzzfInterfaceService.getZfAndManageUsersByUserIds(userIdList);
        Map<String,Object> paramMap=new HashMap<>();
        paramMap.put("userIds",userIdList);
        if(!org.springframework.util.ObjectUtils.isEmpty(userIdList)) {
            List<MemberUserInfo> list=memberUserSignMapper.selectMemberUserInfoByUserIds(paramMap);
            List<CaseHandlePersonRecordVo> handlePersonRecordVos = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
            if (!handlePersonRecordVos.isEmpty()) {
                String hours = term * 24 + "小时";
                for (MemberUserInfo user : list) {
                    if (StringUtils.isNotBlank(user.getZzdAccountid())) {
                        this.sendDingMsg(caseId, documentCatalogCode, user.getRealName(), user.getZzdAccountid(), "newAudit", handlePersonRecordVos.get(0).getHandleOrgName(), hours);
                    }
                }
            }
        }
    }

    /**
     * 工作台-新审批任务提醒
     *
     * @author yangsizhen
     * @date 2022/12/13
     * @param caseId 案件id
     * @param handleOrgName 办案机构
     * @param documentCatalogCode 文书编码
     * @param documentCatalogName 文书名称
     * @param caseApprovalWaitRecord 案件流程实体
     * @param orgCode 用户机构编码
     * @param userIds 用户id集合
     */
    private void sendNewAuditPcMsg(String caseId, String handleOrgName, String documentCatalogCode, String documentCatalogName, CaseApprovalWaitRecord caseApprovalWaitRecord, String orgCode, List<String> userIds) {
        String title = "新的审批任务提示";
        String hours = caseApprovalWaitRecord.getApprovalCurrentLimitTime() * 24 + "小时";
        String msg = "您有一份来自于" + handleOrgName + "的【" + documentCatalogName + "】待审批，审批时效" + hours + "，请前往审批任务列表查看";
        SystemMessageInsertDto dto = new SystemMessageInsertDto();
        dto.setContent(msg);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("caseId", caseId);
        paramMap.put("documentCatalogCode", documentCatalogCode);
        paramMap.put("approvalType", null);
        paramMap.put("documentType", "1");
        paramMap.put("dataSource", null);
        paramMap.put("caseAssistId", caseApprovalWaitRecord.getCaseAssistId());
        paramMap.put("partyId", caseApprovalWaitRecord.getPartyId());
        String json = JSON.toJSONString(paramMap, SerializerFeature.WRITE_MAP_NULL_FEATURES, SerializerFeature.QuoteFieldNames);
        dto.setParamsJson(json);
        dto.setReceiverDept(orgCode);
        dto.setTitle(title);
        dto.setType("1");
        for (String userId : userIds) {
            dto.setReceiverId(userId);
            caseSystemMessageService.insertSystemMessage(dto);
        }
    }

    /**
     * 发送钉钉消息
     * @param caseId 案件ID
     * @param documentCatalogCode 文书目录
     * @param name 用户名
     * @param zwdingAccountId 政务钉钉ID
     * @param dingMsgType 消息类型：auditPass（审核通过），auditRetired（审核退回），newAudit（新的审批）
     */
    private void sendDingMsg(String caseId, String documentCatalogCode, String name, String zwdingAccountId, String dingMsgType, String handleOrgName, String hours){
        try {
            ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("caseId", caseId);
            jsonObject.put("documentCatalogCode", documentCatalogCode);
            jsonObject.put("name", name);
            jsonObject.put("documentCatalogName", configBusiParamDocumentInfo.getDocumentCatalogName());
            jsonObject.put("dingDingId", zwdingAccountId);
            jsonObject.put("url","");
            jsonObject.put("dingMsgType",dingMsgType);
            if(StrUtil.isNotEmpty(hours)){
                jsonObject.put("hours",hours);
            }
            if(StrUtil.isNotEmpty(handleOrgName)){
                jsonObject.put("handleOrgName", handleOrgName);
            }
            //todo 钉消息暂不发送
            BaseUtil.post(dingSendUrl, jsonObject);
        }catch (Exception e){
            log.error("-----------发送钉钉消息失败，caseId：{}, 消息类型：{}--------------", caseId, dingMsgType, e);
        }
    }


}
